package com.macro.mall.controller.callbak;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.dto.MinioUploadDto;
import com.macro.mall.mapper.PmsProductMapper;
import com.macro.mall.mapper.XhsOrderMapper;
import com.macro.mall.model.XhsEncryptedMessage;
import com.macro.mall.model.XhsEncryptedMessageBack;
import com.macro.mall.model.XhsOrder;
import com.macro.mall.service.MinioService;
import com.macro.mall.utils.MsgSignature;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.annotation.Resource;
import java.io.IOException;

// CallbackController.java
@RestController
@RequestMapping("/huadi/xhs")
@RequiredArgsConstructor
@Slf4j
public class CallbackController {

    @Resource
    private XhsOrderMapper xhsOrderMapper;

    private final XhsSignatureService signatureService;
    private final XhsDecryptService decryptService;
    private final XhsConfigProperties config;

    @Resource
    private MinioService minioService;

    @Resource
    private PmsProductMapper productMapper;

    @PostMapping("/callback")
    public String handleCallback(
            @RequestBody String encryptedBody) {

        try {
            log.info("收到小红书URL验证请求: body={}",
                     encryptedBody);


            ObjectMapper objectMapper = new ObjectMapper();
            XhsEncryptedMessageBack xhsEncryptedMessage = objectMapper.readValue(encryptedBody, XhsEncryptedMessageBack.class);

            if (ObjectUtil.isEmpty(xhsEncryptedMessage)){
                log.error("签名转换失败");
            }

            // 1. 验证签名
            boolean valid = signatureService.verifySignature(
                    xhsEncryptedMessage.getMsgSignature(),
                    "zhijia",
                    String.valueOf(xhsEncryptedMessage.getTimestamp()),
                    xhsEncryptedMessage.getNonce(),
                    xhsEncryptedMessage.getEncrypt()
            );

            if (!valid) {
                log.error("签名验证失败");
                return "signature invalid";
            }

            // 2. 解密消息
            String decrypted = decryptService.decrypt(
                    xhsEncryptedMessage.getEncrypt(),
                    "TXoPG5f1oe8Vx1420CSb5ZVI5yeQhKYR492rQjaqylk"
            );

            log.info("解密消息："+decrypted);
            // 3. 解析JSON
            PayResultNotification notification = parseNotification(decrypted);

            log.info("解析后的json："+notification.toString());
            // 4. 处理业务逻辑
            processNotification(notification);

            return "success";

        } catch (Exception e) {
            log.error("处理小红书回调异常", e);
            return "error";
        }
    }


    /**
     * URL验证接口(GET请求)
     */
    @GetMapping("/callback")
    public String verifyUrl(
            @RequestParam("signature") String signature,
            @RequestParam("timestamp") String timestamp,
            @RequestParam("nonce") String nonce,
            @RequestParam("echostr") String echostr) {

        log.info("收到小红书URL验证请求test: signature={}, timestamp={}, nonce={}, echostr={}",
                signature, timestamp, nonce, echostr);

        // 计算签名
        String calculatedSignature = null;
        try {
            calculatedSignature = MsgSignature.getSignature("zhijia", timestamp, nonce, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 验证签名
        if (calculatedSignature.equals(signature)) {
            log.info("URL验证成功");
            return echostr;
        }

        log.error("URL验证失败: 签名不匹配");
        return "signature verification failed";
    }

    private PayResultNotification parseNotification(String json) throws IOException {
        log.info("==========开始参数转换===========");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  // 忽略未知字段
        return objectMapper.readValue(json, PayResultNotification.class);
    }
    private void processNotification(PayResultNotification notification) {
        if (!"PAY_RESULT".equals(notification.getEvent())) {
            return;
        }

        switch (notification.getOrderType()) {
            case 1:
                handleMainOrder(notification);
                break;
            case 2:
                handleBookOrder(notification);
                break;
            default:
                log.warn("未知订单类型: {}", notification.getOrderType());
        }
    }

    private void handleMainOrder(PayResultNotification notification) {
        log.info("处理主单支付结果: {}", notification);

        if (notification.getStatus() == 2) {
            // 支付成功逻辑
            log.info("主单支付成功: orderId={}, amount={}",
                    notification.getOrderId(),
                    notification.getTotalAmount());

            // 处理券码
            if (notification.getVoucherInfos() != null) {
                notification.getVoucherInfos().forEach(voucher -> {
                    log.info("处理券码: {}", voucher.getVoucherCode());

                    CommonResult<MinioUploadDto> minioUploadDtoCommonResult = minioService.uploadQRCode(voucher.getVoucherCode());
                    String url = minioUploadDtoCommonResult.getData().getUrl();
                    log.info("券码转化为二维码url：{}",url);

                    // 保存券码到数据库等操作
                    xhsOrderMapper.updateVoucherCode( notification.getOrderId() , voucher.getVoucherCode(),url);
                    // 修改订单状态为已支付
                    xhsOrderMapper.updateStatusByXHSCallBac(notification.getOrderId(),1);
                    // 增加销量
                    XhsOrder xhsOrder = xhsOrderMapper.selectByXhsOrderId(notification.getOrderId());
                    productMapper.updateSale(xhsOrder.getProductId());

                });
            }
        } else if (notification.getStatus() == 998) {
            // 支付取消逻辑
            log.info("主单支付取消: orderId={}", notification.getOrderId());
        }
    }

    private void handleBookOrder(PayResultNotification notification) {
        log.info("处理预约单支付结果: {}", notification);

        if (notification.getStatus() == 2) {
            log.info("预约单支付成功: orderId={}, amount={}",
                    notification.getOrderId(),
                    notification.getTotalAmount());
        }
    }
}
